//
// Created by LiuYou on 2021/10/28.
//

#include <iostream>
#include <fcntl.h>
#include <unistd.h>


static const int BUF_SIZE = 1024;
static int fd1;
static int fd2;


static off_t calculateFileSize(int fd) {
    off_t offset = lseek( fd, 0, SEEK_END );
    lseek( fd, 0, SEEK_SET );
    return offset;
}


static off_t calculatePos(int fd, int line) {
    // 11 需要10个\n。
    char buf[1]{};
    int lineCount{};
    while (true) {

        read( fd, buf, 1 );
        if (buf[0] == '\n') {
            ++lineCount;
            if (lineCount == line - 1) {
                break;
            }
        }


    }

    off_t offset = lseek( fd, 0, SEEK_CUR );
    return offset;
}


[[deprecated("需要继续进行重构。")]]
//static int calculatePos(int fd, int line) {
//    // 11 需要10个\n。
//    char buf[1]{};
//    int lineCount{};
//    while (true) {
//
//        read( fd, buf, 1 );
//        if (buf[0] == '\n') {
//            ++lineCount;
//            if (lineCount == line - 1) {
//                break;
//            }
//        }
//
//
//    }
//
//    return 0;
//}


[[deprecated("需要进行重构。")]]
//static off_t calculatePos(int fd, int line) {
//    // 11 需要10个\n。
//    char buf[1]{};
//    int lineCount{};
//    while (true) {
//
//        read( fd, buf, 1 );
//        if (buf[0] == '\n') {
//            ++lineCount;
//            if (lineCount == line - 1) {
//                break;
//            }
//        }
//
//
//    }
//
//    off_t offset = lseek( fd, 0, SEEK_CUR );
//    return offset;
//}


[[deprecated("需要进行重构。")]]
static off_t calculatePos11(int fd) {
    // 11 需要10个\n。
    char buf[1]{};
    int lineCount{};
    while (true) {

        read( fd, buf, 1 );
        if (buf[0] == '\n') {
            ++lineCount;
            if (lineCount == 10) {
                break;
            }
        }


    }

    off_t offset = lseek( fd, 0, SEEK_CUR );
    return offset;
}


int main(int argc, char** argv) {
    if (argc < 2) {
        fprintf( stderr, "用法: %s filename\n", argv[0] );
        return 1;
    }

    fd1 = open( argv[1], O_RDONLY );
    if (fd1 < 0) {
        perror( "open()" );
        return 1;
    }
    atexit( [] {
        close( fd1 );
    } );

    fd2 = open( argv[1], O_RDWR );
    if (fd2 < 0) {
        perror( "open()" );
        return 1;
    }
    atexit( [] {
        close( fd2 );
    } );



    // fd1 -> 11
    // fd2 -> 10



    off_t fileSize = calculateFileSize( fd1 );

    off_t offset11 = calculatePos( fd1, 11 );
    off_t offset10 = calculatePos( fd2, 10 );
    off_t truncateSize = offset11 - offset10;


    char buf[BUF_SIZE]{};
    while (true) {
        ssize_t readBytes = read( fd1, buf, BUF_SIZE );
        if (readBytes == 0) {
            break;
        }

        write( fd2, buf, readBytes );

    }

    fileSize -= truncateSize;

    int fd = open( argv[1], O_WRONLY );

    // todo 笔记: 注意:
    //  使用 ftruncate()，文件必须打开才能写入；使用 truncate()，文件必须是可写的。
    int ret = ftruncate( fd, fileSize );
    if (ret < 0) {
        perror( "ftruncate()" );
        return 1;
    }


    return 0;
}
